package top.roadvast.network.server;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;

/**
 * @Author 郭泽鹏
 * @Date 2021/12/31 17:25
 * @Version 1.0
 * @Description
 *      文件上传案例服务器端：读取服务器上传的文件，保存到服务器的硬盘，给客户端回写“上传成功”
 *
 *      明确：
 *          数据源：客户端上传的文件
 *          目的地：服务器的硬盘： D:\IDEA\java-study\java-basic\network-programming\output
 *
 *      实现步骤：
 *          1.创建一个服务器ServerSocket对象，和系统要指定的端口
 *          2.使用ServerSocket对象中的方法accept，获取到请求的客户端Socket对象
 *          3.使用Socket对象中的方法getInputStream，获取到网络字节输入流InputStream对象
 *          4.判断 d:\\upload 文件夹是否存在，不存在则创建
 *          5.创建一个本地字节输出流FileOutputStream对象，构造方法中绑定要输出的目的地
 *          6.使用网络字节输入流InputStream的read方法，读取客户端上传的文件
 *          7.使用本地字节输出流FileOutputStream对象中的write方法，把读取到的文件保存到服务器的硬盘上
 *          8.使用Socket对象中的getOutputStream，获取网络字节输出流OuputStream对象
 *          9.使用网络字节输出流OutputStream的write方法，给客户端回写“上传成功”
 *          10.释放资源（FileOutputStream，Socket，ServerSocket）
 */
public class TCPFileServer {
    public static void main(String[] args) {
        System.setProperty("user.dir", System.getProperty("user.dir") + "/java-basic/network-programming/");
        ServerSocket serverSocket = null;
        try {
            //创建serverSocket，并绑定端口
            serverSocket = new ServerSocket(8084);
            System.out.println("服务器端已启动.");
            System.out.println("等待客户端连接...");
            while (true) {
                //阻塞，等待接收客户端请求套接字
                Socket socket = serverSocket.accept();
                new Thread(() -> {
                    System.out.println("===========客户端[" + socket.getInetAddress() + ":"
                            + socket.getPort() + "]已连接，正在进行交互===========");
                    InputStream inputStream = null;
                    OutputStream outputStream = null;
                    FileOutputStream fileOutputStream = null;
                    try {
                        //文件名
                        final String fileName = UUID.randomUUID().toString().replaceAll("-", "");
                        //文件输出位置
                        File file = new File(System.getProperty("user.dir") + "/output/");
                        System.out.println(file.getPath());
                        if (!file.exists()) {       //文件夹不存在就创建
                            file.mkdirs();
                        }
                        fileOutputStream = new FileOutputStream(file  + "/" + fileName + ".png");
                        //获取输入流
                        inputStream = socket.getInputStream();
                        //缓冲区
                        byte[] bytes = new byte[1024];
                        //读取客户端数据返回的长度，-1表示已经读完
                        int len = -1;
                        //接收数据，存储在bytes中，然后返回长度
                        while ((len = inputStream.read(bytes)) != -1) {
                            fileOutputStream.write(bytes, 0, len);      //将图片进行存储
                        }
                        System.out.println("上传成功.");
                        //返回响应
                        outputStream = socket.getOutputStream();
                        String response = "上传成功.";
                        outputStream.write(response.getBytes());
                        System.out.println("+++++已响应消息+++++");
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (fileOutputStream != null) {
                                fileOutputStream.close();
                            }
                            if (inputStream != null) {
                                inputStream.close();
                            }
                            if (outputStream != null) {
                                outputStream.close();
                            }
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}
